﻿using System;
using System.Collections.Generic;
using System.Linq;
using MethodWorx.CMS.Content;
using MethodWorx.CMS.Providers;
using MethodWorx.CMS.Web;
using MethodWorx.CMS.TemplateLanguage;
using MethodWorx.CMS.Configuration;
using MethodWorx.CMS.Administration;
using MethodWorx.CMS.Plugins;
using MethodWorx.CMS.TemplateParser;
using System.Reflection;
using MethodWorx.CMS.TemplateParser.Compiler;
using MethodWorx.CMS.Services;
using StructureMap;

namespace MethodWorx.CMS.WebHost
{
    public partial class _Page : System.Web.UI.Page
    {
        private static Dictionary<string, Type> compiledPages = new Dictionary<string, Type>();

        protected void Page_Load(object sender, EventArgs e)
        {

        
        }

        public Page CmsPage
        {
            get { return this.CmsRequestContext.Page; }
        }

        public CmsRequestContext CmsRequestContext
        {
            get
            {
                return CmsRequestContext.Current;
            }
        }

        public PageTemplate CmsPageTemplate
        {
            get { return this.CmsPage.Template; }
        }

        public string Output
        {
            get 
            {
                
                    PluginService service =
                    new PluginService(
                        WebConfiguration.Instance.Provider.GetUnitOfWorkFactory(),
                        WebConfiguration.Instance.Provider.GetService<IPluginUserDataRepository>(),
                        WebConfiguration.Instance.Provider.GetService<IPluginRepository>());

                var applicationSettings =
                    WebConfiguration.Instance.Provider.GetService<IApplicationSettingsRepository>();

                var plugins = new PluginRepository(
                    WebConfiguration.Instance.Provider,
                    WebConfiguration.Instance.Provider.GetUnitOfWorkFactory(),
                    WebConfiguration.Instance.Provider.GetRepositoryRegistry());


                var parsingEngine = new ParsingEngine(WebConfiguration.Instance.Provider, this.CmsRequestContext.Page.Template,
                                                      new PluginFactory(applicationSettings, plugins), null);

                object instance = null;
                TemplateCompiler compiler = new TemplateCompiler((ICmsDataProvider)null);
                var key = this.CmsPageTemplate.Id + "_" + (this.CmsPageTemplate.DatePublished ?? DateTime.Now).Ticks;
                if(compiledPages.ContainsKey(key))
                {
                    var type = compiledPages[key];
                    instance = TemplateCompiler.CreateTemplateInstance(type,  parsingEngine, CmsRequestContext.Current, (t) => WebConfiguration.Instance.GetService(t));
                }
                else
                {
                    var type = compiler.Compile(this.CmsPage.PublishedTemplate);
                    compiledPages.Add(key, type);
                    instance = TemplateCompiler.CreateTemplateInstance(type, parsingEngine, CmsRequestContext.Current, (t) => WebConfiguration.Instance.GetService(t));

                }

                var variables = new Dictionary<string, object>();
                variables.Add("~", this.ResolveUrl("~/"));
                return (string)instance.GetType().InvokeMember("Execute",
                                                BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
                                                null, instance, new object[] { variables });
            }
        }
    }
}
